package main

import (
	"embed"
	"go-im/src/router"
	"io/fs"
	"log"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
)

//go:embed public/**
var embeddedFiles embed.FS

//	@title			这里写标题
//	@version		1.0
//	@description	这里写描述信息
//	@termsOfService	http://swagger.io/terms/

//	@contact.name	这里写联系人信息
//	@contact.url	http://www.swagger.io/support
//	@contact.email	support@swagger.io

//	@license.name	Apache 2.0
//	@license.url	http://www.apache.org/licenses/LICENSE-2.0.html

// @host		这里写接口服务的host
// @BasePath	这里写base path
func main() {

	gin.SetMode(gin.ReleaseMode)
	r := router.Router()

	// 静态文件
	var envPort string = "8000" // 监听端口
	mux := http.NewServeMux()
	staticFiles, err := fs.Sub(embeddedFiles, "public")
	if err != nil {
		log.Println(err)
		return
	}
	fileServer := http.FileServer(http.FS(staticFiles))
	mux.Handle("/", fileServer)
	log.Println("debug: can do here?")
	// 使用 CORS 中间件和日志中间件
	handler := corsMiddleware(logAccessMiddleware(mux))

	log.Printf("Server is running on http://localhost:%s\n", envPort)
	err = http.ListenAndServe(":"+envPort, handler)
	//todo:  ？
	r.Run(":8080")
	log.Println("debug: are we running")

}

// CORS 中间件
func corsMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// 设置允许的来源
		w.Header().Set("Access-Control-Allow-Origin", "*")

		// 允许的方法
		w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")

		// 允许的请求头
		w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, Authorization")

		// 允许暴露的响应头
		w.Header().Set("Access-Control-Expose-Headers", "Authorization")

		// 允许凭证
		w.Header().Set("Access-Control-Allow-Credentials", "true")

		// 缓存预检请求结果
		w.Header().Set("Access-Control-Max-Age", "86400")

		// 处理预检请求
		if r.Method == "OPTIONS" {
			w.WriteHeader(http.StatusOK)
			return
		}

		next.ServeHTTP(w, r)
	})
}

// 记录访问日志的中间件
func logAccessMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		// 创建一个响应记录器来捕获状态码
		lrw := &loggingResponseWriter{ResponseWriter: w, statusCode: http.StatusOK}
		next.ServeHTTP(lrw, r)
		duration := time.Since(start)
		log.Printf("%s - %s %s %d %v", r.RemoteAddr, r.Method, r.URL.Path, lrw.statusCode, duration)
	})
}

// 自定义响应写入器，用于记录状态码
type loggingResponseWriter struct {
	http.ResponseWriter
	statusCode int
}
